From 69ab514aefe770ed16f823286c488eee24610bef Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Date: Fri, 9 Jul 2004 22:44:35 +0000 Subject: [PATCH] Bug 113310. Sat Jul 10 00:37:45 2004 Soeren Sandmann Bug 113310. * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg): New functions that can do a recursive unset/reset bg. * gdk/x11/gdkgeometry-x11.c: Remove gdk_window_tmp_{un|re}set_bg(). * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions called before and after unmapping a window. They unset the background of all other windows to prevent flicker from the X server repainting the background. post_unmap() also invalidates the parent of the unmapped window to draw it without roundtrips. * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset background of newly mapped windows and all desendants to prevent flicker. --- ChangeLog | 22 +++++ ChangeLog.pre-2-10 | 22 +++++ ChangeLog.pre-2-6 | 22 +++++ ChangeLog.pre-2-8 | 22 +++++ gdk/x11/gdkgeometry-x11.c | 65 ++------------ gdk/x11/gdkwindow-x11.c | 178 ++++++++++++++++++++++++++++++++++++++ gdk/x11/gdkwindow-x11.h | 5 ++ 7 files changed, 278 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd2cb7b3d6..9e6286cb85 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +Sat Jul 10 00:37:45 2004 Soeren Sandmann + + Bug 113310. + + * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg): + New functions that can do a recursive unset/reset bg. + + * gdk/x11/gdkgeometry-x11.c: Remove + gdk_window_tmp_{un|re}set_bg(). + + * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions + called before and after unmapping a window. They unset the + background of all other windows to prevent flicker from the X + server repainting the background. post_unmap() also invalidates + the parent of the unmapped window to draw it without roundtrips. + + * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset + background of newly mapped windows and all desendants to prevent + flicker. + Fri Jul 9 15:33:55 2004 Manish Singh * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch @@ -8,6 +28,8 @@ Fri Jul 9 15:33:55 2004 Manish Singh Fri Jul 9 23:26:09 2004 Soeren Sandmann + (Bug 113340) + * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an "override_redirect" bit. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index cd2cb7b3d6..9e6286cb85 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,23 @@ +Sat Jul 10 00:37:45 2004 Soeren Sandmann + + Bug 113310. + + * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg): + New functions that can do a recursive unset/reset bg. + + * gdk/x11/gdkgeometry-x11.c: Remove + gdk_window_tmp_{un|re}set_bg(). + + * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions + called before and after unmapping a window. They unset the + background of all other windows to prevent flicker from the X + server repainting the background. post_unmap() also invalidates + the parent of the unmapped window to draw it without roundtrips. + + * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset + background of newly mapped windows and all desendants to prevent + flicker. + Fri Jul 9 15:33:55 2004 Manish Singh * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch @@ -8,6 +28,8 @@ Fri Jul 9 15:33:55 2004 Manish Singh Fri Jul 9 23:26:09 2004 Soeren Sandmann + (Bug 113340) + * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an "override_redirect" bit. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index cd2cb7b3d6..9e6286cb85 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,23 @@ +Sat Jul 10 00:37:45 2004 Soeren Sandmann + + Bug 113310. + + * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg): + New functions that can do a recursive unset/reset bg. + + * gdk/x11/gdkgeometry-x11.c: Remove + gdk_window_tmp_{un|re}set_bg(). + + * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions + called before and after unmapping a window. They unset the + background of all other windows to prevent flicker from the X + server repainting the background. post_unmap() also invalidates + the parent of the unmapped window to draw it without roundtrips. + + * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset + background of newly mapped windows and all desendants to prevent + flicker. + Fri Jul 9 15:33:55 2004 Manish Singh * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch @@ -8,6 +28,8 @@ Fri Jul 9 15:33:55 2004 Manish Singh Fri Jul 9 23:26:09 2004 Soeren Sandmann + (Bug 113340) + * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an "override_redirect" bit. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index cd2cb7b3d6..9e6286cb85 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,23 @@ +Sat Jul 10 00:37:45 2004 Soeren Sandmann + + Bug 113310. + + * gdk/x11/gdkwindow-x11.c (_gdk_x11_window_tmp_{un|re}set_bg): + New functions that can do a recursive unset/reset bg. + + * gdk/x11/gdkgeometry-x11.c: Remove + gdk_window_tmp_{un|re}set_bg(). + + * gdk/x11/gdkwindow-x11.c (pre_unmap, post_unmap): New functions + called before and after unmapping a window. They unset the + background of all other windows to prevent flicker from the X + server repainting the background. post_unmap() also invalidates + the parent of the unmapped window to draw it without roundtrips. + + * gdk/x11/gdkwindow-x11.c (show_window_internal): Unset + background of newly mapped windows and all desendants to prevent + flicker. + Fri Jul 9 15:33:55 2004 Manish Singh * gdk/gdkevents.c: have a dummy case GDK_OWNER_CHANGE in switch @@ -8,6 +28,8 @@ Fri Jul 9 15:33:55 2004 Manish Singh Fri Jul 9 23:26:09 2004 Soeren Sandmann + (Bug 113340) + * gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Add an "override_redirect" bit. diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index 08af4c22d7..3620495212 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -137,6 +137,7 @@ #include "gdkinternals.h" #include "gdkscreen-x11.h" #include "gdkdisplay-x11.h" +#include "gdkwindow-x11.h" typedef struct _GdkWindowQueueItem GdkWindowQueueItem; typedef struct _GdkWindowParentPos GdkWindowParentPos; @@ -183,8 +184,6 @@ static void gdk_window_postmove (GdkWindow *window, static void gdk_window_queue_translation (GdkWindow *window, gint dx, gint dy); -static void gdk_window_tmp_unset_bg (GdkWindow *window); -static void gdk_window_tmp_reset_bg (GdkWindow *window); static void gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip); @@ -324,7 +323,7 @@ gdk_window_guffaw_scroll (GdkWindow *window, parent_pos.x11_y += new_info.y; parent_pos.clip_rect = new_info.clip_rect; - gdk_window_tmp_unset_bg (window); + _gdk_x11_window_tmp_unset_bg (window, FALSE);; if (dx > 0 || dy > 0) gdk_window_queue_translation (window, MAX (dx, 0), MAX (dy, 0)); @@ -361,7 +360,7 @@ gdk_window_guffaw_scroll (GdkWindow *window, impl->position_info.width, impl->position_info.height); if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + _gdk_x11_window_tmp_reset_bg (window, FALSE); impl->position_info = new_info; @@ -548,7 +547,7 @@ _gdk_window_move_resize_child (GdkWindow *window, new_info.x, new_info.y, new_info.width, new_info.height); if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + _gdk_x11_window_tmp_reset_bg (window, FALSE); if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); @@ -594,7 +593,7 @@ _gdk_window_move_resize_child (GdkWindow *window, } if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + _gdk_x11_window_tmp_reset_bg (window, FALSE); if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); @@ -854,7 +853,7 @@ gdk_window_postmove (GdkWindow *window, XMapWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window)); if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + _gdk_x11_window_tmp_reset_bg (window, FALSE); impl->position_info = new_info; @@ -1063,56 +1062,6 @@ _gdk_window_process_expose (GdkWindow *window, gdk_region_destroy (clip_region); } -static void -gdk_window_tmp_unset_bg (GdkWindow *window) -{ - GdkWindowImplX11 *impl; - GdkWindowObject *obj; - - obj = (GdkWindowObject *) window; - impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - impl->position_info.no_bg = TRUE; - - if (obj->bg_pixmap != GDK_NO_BG) - XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), None); -} - -static void -gdk_window_tmp_reset_bg (GdkWindow *window) -{ - GdkWindowImplX11 *impl; - GdkWindowObject *obj; - - obj = (GdkWindowObject *) window; - impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - impl->position_info.no_bg = FALSE; - - if (obj->bg_pixmap == GDK_NO_BG) - return; - - if (obj->bg_pixmap) - { - Pixmap xpixmap; - - if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG) - xpixmap = ParentRelative; - else - xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap); - - XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), xpixmap); - } - else - { - XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), - obj->bg_color.pixel); - } -} - static void gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip) { @@ -1145,7 +1094,7 @@ gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle gdk_region_subtract (new_clip_region, old_clip_region); if (!gdk_region_empty (new_clip_region)) { - gdk_window_tmp_unset_bg (window); + _gdk_x11_window_tmp_unset_bg (window, FALSE);; gdk_window_invalidate_region (window, new_clip_region, FALSE); } diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index e764de8ff8..0214177f41 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -217,6 +217,118 @@ gdk_window_impl_x11_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +tmp_unset_bg (GdkWindow *window) +{ + GdkWindowImplX11 *impl; + GdkWindowObject *obj; + + obj = (GdkWindowObject *) window; + impl = GDK_WINDOW_IMPL_X11 (obj->impl); + + impl->position_info.no_bg = TRUE; + + if (obj->bg_pixmap != GDK_NO_BG) + XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), + GDK_DRAWABLE_XID (window), None); +} + +static void +tmp_reset_bg (GdkWindow *window) +{ + GdkWindowImplX11 *impl; + GdkWindowObject *obj; + + obj = (GdkWindowObject *) window; + impl = GDK_WINDOW_IMPL_X11 (obj->impl); + + impl->position_info.no_bg = FALSE; + + if (obj->bg_pixmap == GDK_NO_BG) + return; + + if (obj->bg_pixmap) + { + Pixmap xpixmap; + + if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG) + xpixmap = ParentRelative; + else + xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap); + + XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), + GDK_DRAWABLE_XID (window), xpixmap); + } + else + { + XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window), + GDK_DRAWABLE_XID (window), + obj->bg_color.pixel); + } +} + +void +_gdk_x11_window_tmp_unset_bg (GdkWindow *window, + gboolean recurse) +{ + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *)window; + + if (private->input_only || private->destroyed || !GDK_WINDOW_IS_MAPPED (window)) + return; + + /* Don't unset the background of windows that don't select for expose + * events. Such windows don't get drawn, so we need the X server + * drawing them to prevent them from containing garbage + */ + if (private->window_type != GDK_WINDOW_ROOT && + private->window_type != GDK_WINDOW_FOREIGN && + (private->event_mask & GDK_EXPOSURE_MASK)) + { + tmp_unset_bg (window); + } + + if (recurse) + { + GList *l; + + for (l = private->children; l != NULL; l = l->next) + _gdk_x11_window_tmp_unset_bg (l->data, TRUE); + } +} + +void +_gdk_x11_window_tmp_reset_bg (GdkWindow *window, + gboolean recurse) +{ + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *)window; + + if (private->input_only || private->destroyed || !GDK_WINDOW_IS_MAPPED (window)) + return; + + if (private->window_type != GDK_WINDOW_ROOT && + private->window_type != GDK_WINDOW_FOREIGN && + (private->event_mask & GDK_EXPOSURE_MASK)) + { + tmp_reset_bg (window); + } + + if (recurse) + { + GList *l; + + for (l = private->children; l != NULL; l = l->next) + _gdk_x11_window_tmp_reset_bg (l->data, TRUE); + } +} + static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable) { @@ -987,6 +1099,14 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window) gdk_error_trap_pop (); } +static GdkWindow * +get_root (GdkWindow *window) +{ + GdkScreen *screen = gdk_drawable_get_screen (window); + + return gdk_screen_get_root_window (screen); +} + /* This function is called when the XWindow is really gone. */ void @@ -1227,6 +1347,7 @@ show_window_internal (GdkWindow *window, impl->override_redirect) && gdk_window_is_viewable (window)) { + _gdk_x11_window_tmp_reset_bg (window, TRUE); gdk_window_invalidate_rect (window, NULL, TRUE); } } @@ -1277,6 +1398,55 @@ gdk_window_show (GdkWindow *window) show_window_internal (window, TRUE); } +static void +pre_unmap (GdkWindow *window) +{ + GdkWindow *start_window = NULL; + GdkWindowObject *private = (GdkWindowObject *)window; + + if (private->input_only) + return; + + if (private->window_type == GDK_WINDOW_CHILD) + start_window = (GdkWindow *)private->parent; + else if (private->window_type == GDK_WINDOW_TEMP) + start_window = get_root (window); + + if (start_window) + _gdk_x11_window_tmp_unset_bg (start_window, TRUE); +} + +static void +post_unmap (GdkWindow *window) +{ + GdkWindow *start_window = NULL; + GdkWindowObject *private = (GdkWindowObject *)window; + + if (private->input_only) + return; + + if (private->window_type == GDK_WINDOW_CHILD) + start_window = private->parent; + else if (private->window_type == GDK_WINDOW_TEMP) + start_window = get_root (window); + + if (start_window) + { + _gdk_x11_window_tmp_reset_bg (start_window, TRUE); + + if (private->window_type == GDK_WINDOW_CHILD && private->parent) + { + GdkRectangle invalid_rect; + + gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y); + gdk_drawable_get_size (GDK_DRAWABLE (window), + &invalid_rect.width, &invalid_rect.height); + gdk_window_invalidate_rect ((GdkWindow *)private->parent, + &invalid_rect, TRUE); + } + } +} + /** * gdk_window_hide: * @window: a #GdkWindow @@ -1329,9 +1499,13 @@ gdk_window_hide (GdkWindow *window) g_assert (!GDK_WINDOW_IS_MAPPED (window)); _gdk_window_clear_update_area (window); + + pre_unmap (window); XUnmapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); + + post_unmap (window); } } @@ -1360,9 +1534,13 @@ gdk_window_withdraw (GdkWindow *window) GDK_WINDOW_STATE_WITHDRAWN); g_assert (!GDK_WINDOW_IS_MAPPED (window)); + + pre_unmap (window); XWithdrawWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), 0); + + post_unmap (window); } } diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h index 4e726f4b80..e2f160bd73 100644 --- a/gdk/x11/gdkwindow-x11.h +++ b/gdk/x11/gdkwindow-x11.h @@ -127,6 +127,11 @@ GType gdk_window_impl_x11_get_type (void); GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window); void gdk_x11_window_set_user_time (GdkWindow *window, guint32 timestamp); +void _gdk_x11_window_tmp_unset_bg (GdkWindow *window, + gboolean recurse); +void _gdk_x11_window_tmp_reset_bg (GdkWindow *window, + gboolean recurse); + G_END_DECLS -- 2.30.2